#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
抖音电商(DY) 爬虫配置文件
参考JD架构，适配抖音电商特点
"""

import os
from typing import Dict, List, Any

class DYConfig:
    """抖音电商爬虫配置"""
    
    # ==================== 基础配置 ====================
    
    # 驱动路径
    BASE_DIR = os.path.dirname(os.path.abspath(__file__))
    CHROME_DRIVER_PATH = os.path.join(BASE_DIR, 'chromedriver.exe')
    
    # 输出目录
    OUTPUT_DIR = os.path.join(BASE_DIR, 'output')
    
    # 日志配置
    LOG_LEVEL = 'INFO'
    LOG_FORMAT = '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
    
    # ==================== 抖音电商URL配置 ====================
    
    # 登录相关URL
    LOGIN_URL = "https://fxg.jinritemai.com/login/common"
    LOGIN_SUCCESS_INDICATORS = [
        "fxg.jinritemai.com/dashboard",
        "fxg.jinritemai.com/home",
        "fxg.jinritemai.com/shop"
    ]
    
    # 商家后台基础URL
    BASE_URL = "https://fxg.jinritemai.com"
    
    # ==================== 页面元素选择器 ====================
    
    # 登录页面选择器
    LOGIN_SELECTORS = {
        # 登录方式选择
        'login_tabs': [
            'div[data-testid="login-tab"]',
            '.login-tab-item',
            '.login-method-tab'
        ],
        
        # 手机号登录相关
        'phone_input': [
            'input[placeholder*="手机号"]',
            'input[placeholder*="请输入手机号"]',
            'input[type="tel"]',
            'input[name="phone"]'
        ],
        
        # 验证码相关
        'captcha_input': [
            'input[placeholder*="验证码"]',
            'input[placeholder*="请输入验证码"]',
            'input[name="captcha"]',
            'input[name="code"]'
        ],
        
        'get_captcha_btn': [
            'button:contains("获取验证码")',
            'button:contains("发送验证码")',
            '.captcha-btn',
            '.get-code-btn'
        ],
        
        # 登录按钮
        'login_btn': [
            'button:contains("登录")',
            'button[type="submit"]',
            '.login-btn',
            '.submit-btn'
        ],
        
        # 用户协议
        'agreement_checkbox': [
            'input[type="checkbox"]',
            '.checkbox-input',
            '.agreement-checkbox'
        ],
        
        # 登录状态指示器
        'login_success_indicators': [
            '.user-info',
            '.user-avatar',
            '.dashboard-header',
            '.shop-info'
        ]
    }
    
    # 商品列表页面选择器
    PRODUCT_LIST_SELECTORS = {
        # 商品卡片容器
        'product_cards': [
            '.product-item',
            '.goods-item',
            '.product-card',
            'div[data-testid="product-item"]'
        ],
        
        # 商品信息
        'product_title': [
            '.product-title',
            '.goods-name',
            '.product-name',
            'h3', 'h4'
        ],
        
        'product_image': [
            '.product-img img',
            '.goods-img img',
            '.product-image img'
        ],
        
        'product_price': [
            '.price',
            '.product-price',
            '.goods-price',
            '.price-current'
        ],
        
        'product_link': [
            '.product-item a',
            '.goods-item a',
            'a[href*="/product/"]',
            'a[href*="/goods/"]'
        ],
        
        # 分页相关
        'pagination_container': [
            '.pagination',
            '.page-container',
            '.ant-pagination'
        ],
        
        'next_page_btn': [
            '.ant-pagination-next',
            '.pagination-next',
            'button:contains("下一页")',
            'a:contains("下一页")'
        ],
        
        'page_numbers': [
            '.ant-pagination-item',
            '.page-number',
            '.pagination-item'
        ],
        
        'total_count': [
            '.total-count',
            '.goods-total',
            '.result-count'
        ]
    }
    
    # 商品详情页面选择器
    PRODUCT_DETAIL_SELECTORS = {
        # 基础信息
        'product_title': [
            '.product-title',
            '.goods-title',
            'h1', 'h2'
        ],
        
        'product_price': [
            '.price-current',
            '.current-price',
            '.selling-price'
        ],
        
        'product_images': [
            '.product-gallery img',
            '.goods-images img',
            '.detail-images img'
        ],
        
        # 商品详情
        'product_description': [
            '.product-desc',
            '.goods-description',
            '.detail-content'
        ],
        
        'product_specs': [
            '.product-specs',
            '.goods-params',
            '.spec-list'
        ],
        
        # 销售信息
        'sales_count': [
            '.sales-count',
            '.sold-count',
            '.sales-info'
        ],
        
        'stock_count': [
            '.stock-count',
            '.inventory-count',
            '.stock-info'
        ]
    }
    
    # ==================== 浏览器配置 ====================
    
    # User-Agent列表（抖音电商适配）
    USER_AGENTS = [
        'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36',
        'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36',
        'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36',
        'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36',
        'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36'
    ]
    
    @classmethod
    def get_random_user_agent(cls) -> str:
        """获取随机User-Agent"""
        import random
        return random.choice(cls.USER_AGENTS)
    
    # Chrome选项配置
    CHROME_OPTIONS = [
        '--no-sandbox',
        '--disable-dev-shm-usage',
        '--disable-gpu',
        '--disable-web-security',
        '--disable-features=VizDisplayCompositor',
        '--disable-blink-features=AutomationControlled',
        '--exclude-switches=enable-automation',
        '--disable-extensions',
        '--disable-plugins',
        '--disable-images',  # 禁用图片加载提升速度
        '--no-first-run',
        '--no-default-browser-check',
        '--ignore-certificate-errors',
        '--ignore-ssl-errors',
        '--ignore-certificate-errors-spki-list',
        '--disable-logging',
        '--disable-default-apps',
        '--disable-background-timer-throttling',
        '--disable-renderer-backgrounding',
        '--disable-backgrounding-occluded-windows',
        '--disable-client-side-phishing-detection',
        '--disable-crash-reporter',
        '--disable-oopr-debug-crash-dump',
        '--no-crash-upload',
        '--disable-low-res-tiling',
        '--log-level=3'
    ]
    
    # 反检测设置
    ANTI_DETECTION_SCRIPT = """
        Object.defineProperty(navigator, 'webdriver', {
            get: () => undefined,
        });
        
        Object.defineProperty(navigator, 'languages', {
            get: () => ['zh-CN', 'zh', 'en'],
        });
        
        Object.defineProperty(navigator, 'plugins', {
            get: () => [1, 2, 3, 4, 5],
        });
        
        window.chrome = {
            runtime: {},
        };
        
        Object.defineProperty(navigator, 'permissions', {
            get: () => ({
                query: () => Promise.resolve({ state: 'granted' }),
            }),
        });
    """
    
    # ==================== 等待时间配置 ====================
    
    WAIT_TIMES = {
        'implicit_wait': 10,      # 隐式等待
        'page_load_timeout': 30,  # 页面加载超时
        'element_wait': 15,       # 元素等待
        'login_wait': 30,         # 登录等待
        'human_delay_min': 1,     # 人性化延迟最小值
        'human_delay_max': 3,     # 人性化延迟最大值
        'click_delay': 2,         # 点击后延迟
        'scroll_delay': 1,        # 滚动延迟
        'captcha_wait': 60        # 验证码等待时间
    }
    
    # ==================== API配置 ====================
    
    # API相关配置
    API_CONFIG = {
        'base_url': 'http://192.168.5.12:8000',
        'endpoints': {
            'products': '/api/v1/products/batch_add_processed_products/',
        },
        'timeout': 30,
        'max_retries': 3
    }
    
    # ==================== 其他配置 ====================
    
    # 默认爬取配置
    DEFAULT_SETTINGS = {
        'max_pages': 5,           # 默认最大页数
        'max_products_per_page': 20,  # 每页最大商品数
        'max_products_total': 100,    # 总最大商品数
        'enable_details': True,       # 是否获取详情
        'save_images': False,         # 是否保存图片
        'delay_between_requests': (2, 5),  # 请求间延迟范围
    }
    
    # 重试配置
    RETRY_CONFIG = {
        'max_retries': 3,         # 最大重试次数
        'retry_delay': 5,         # 重试间隔
        'exponential_backoff': True  # 指数退避
    }
    
    # 日志文件配置
    LOG_CONFIG = {
        'filename': os.path.join(OUTPUT_DIR, 'dy_scraper.log'),
        'max_size': 10 * 1024 * 1024,  # 10MB
        'backup_count': 5
    }
    
    @classmethod
    def ensure_output_dir(cls):
        """确保输出目录存在"""
        if not os.path.exists(cls.OUTPUT_DIR):
            os.makedirs(cls.OUTPUT_DIR)
    
    @classmethod 
    def get_chrome_options(cls, headless: bool = False) -> List[str]:
        """获取Chrome选项"""
        options = cls.CHROME_OPTIONS.copy()
        if headless:
            options.append('--headless')
        return options
    
    @classmethod
    def validate_config(cls) -> bool:
        """验证配置有效性"""
        try:
            # 检查驱动文件
            if not os.path.exists(cls.CHROME_DRIVER_PATH):
                print(f"❌ ChromeDriver不存在: {cls.CHROME_DRIVER_PATH}")
                return False
            
            # 确保输出目录
            cls.ensure_output_dir()
            
            print("✅ DY配置验证通过")
            return True
            
        except Exception as e:
            print(f"❌ 配置验证失败: {e}")
            return False 